﻿using AgencyManagerSystem.AsmType;
using AgencyManagerSystem.Common;
using AgencyManagerSystem.Core;
using AgencyManagerSystem.Core.Utility;
using AgencyManagerSystem.DataFetcher;
using AgencyManagerSystem.Model;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Net;
using System.Linq;
using System.Text;

namespace AgencyManagerSystem.Controllers
{
    public class UserController : MyControllerBase
    {
        LoginManager manager;
        UserManager uManager;
        LoginFetcher fetcher;
        UserFetcher userFetcher;
        public UserController() : base()
        {
            this.manager = new LoginManager();
            this.fetcher = new LoginFetcher();
            this.userFetcher = new UserFetcher();
            this.uManager = new UserManager();
        }
        [HttpGet]
        [AllowAnonymous]
        public string Test()
        {
            DBHelper.GetTran();
            return "";
        }
        //SAMPLE FOR TICKET {"User":"root","Pasword":"abc","Domain":"1"}
        [HttpPost]
        [AllowAnonymous]
        public AsmToken Login(AsmTicket ticket)
        {
            string message;
            LogHelper.Debug(this.GetType(), String.Format("LOGIN:[RQS|{1}]{0}", Util.ConvertToJson(ticket), RequestIp));
            if (ticket == null || String.IsNullOrWhiteSpace(ticket.User) || String.IsNullOrWhiteSpace(ticket.Password))
            {
                DBHelper.Commit(false);
                LogHelper.Log(this.GetType(), String.Format("LOGIN:从客户端[{0}]中接收到空的参数", RequestIp));
                Response.StatusCode = (int)HttpStatusCode.BadRequest;
                var errResponse = new AsmToken() { LoginTime = Util.Now(), Message = "传入的参数为空", Result = AmsCode.ArgNotAccept };
                LogHelper.Debug(this.GetType(), String.Format("LOGIN:[RSP|{1}]{0}", Util.ConvertToJson(errResponse), RequestIp));
                return errResponse;
            }
            LogHelper.Log(this.GetType(), String.Format("LOGIN:用户{0}尝试从客户端[{1}]中登录", ticket.User, RequestIp));
            int userid = 0;
            bool logSucc = fetcher.GetForLogin(ticket.User, ticket.Password, out message, out userid);
            AsmToken asmLogin = null;
            if (logSucc)
            {
                DateTime loginTime;
                int expires;
                var userModel = userFetcher.Get(userid);
                profile = new UserProfile() { UserId = userid, Domain = ticket.Domain };
                var fullUserProfile = MyHttpContextHelper.ToFullUserProfile(profile);
                if (!MyHttpContext.Current.Items.ContainsKey(Definer.CURRENT_PROFILE))
                {
                    MyHttpContext.Current.Items.Add(Definer.CURRENT_PROFILE, fullUserProfile);
                }
                else
                {
                    MyHttpContext.Current.Items[Definer.CURRENT_PROFILE] = fullUserProfile;
                }
                string token = TokenManager.GenerateToken(profile, out expires, out loginTime);
                manager.UpdateLastLogin(ticket.User);
                asmLogin = new AsmToken()
                {
                    Result = AmsCode.Succ,
                    Message = "登录成功",
                    Data = token,
                    Domain = ticket.Domain,
                    Token = token,
                    UserId = userid,
                    Expires = expires,
                    LoginTime = loginTime.ToString(Util.GetTimeFormat()),
                    IsRetail = userModel.Retail,
                    IsSupplier = userModel.Supplier
                };
                if(asmLogin.IsRetail)
                {
                    var retailMemberFetcher = new RetailMemberFetcher();
                    var retailmember = retailMemberFetcher.GetByUser(asmLogin.UserId);
                    if (retailmember != null)
                        asmLogin.RetailId = retailmember.Retail;
                }
                if (asmLogin.IsSupplier)
                {
                    var supplierMemberFetcher = new SupplierMemberFetcher();
                    var suppliermember = supplierMemberFetcher.GetByUser(asmLogin.UserId);
                    if (suppliermember != null)
                        asmLogin.SupplierId = suppliermember.Supplier;
                }
                LogHelper.Log(this.GetType(), String.Format("用户 [{0}:{1}]从客户端{2}上登录成功", fullUserProfile.UserName, ticket.User, RequestIp));
            }
            else
            {
                asmLogin = new AsmToken()
                {
                    Result = AmsCode.AuthFaild,
                    Message = String.Format("登录失败,{1}[{0}]", ticket.User, message),
                    Domain = ticket.Domain,
                };
                LogHelper.Warn(this.GetType(), String.Format("用户 [{0}] 从客户端{2}上登录失败:{1}", ticket.User, message, RequestIp));
            }
            LogHelper.Debug(this.GetType(), String.Format("LOGIN:[RSP|{1}]{0}", Util.ConvertToJson(asmLogin), RequestIp));
            DBHelper.Commit(true);
            return asmLogin;
        }
        [HttpGet]
        [Authorize]
        public AsmToken GetToken()
        {
            //该方法调用成功后同时会进行token续约
            AsmToken asmLogin = new AsmToken();
            if (profile != null)
            {
                asmLogin.Result = AmsCode.Succ;
                asmLogin.Message = "刷新成功";
                DateTime loginTime;
                int expires;
                asmLogin.UserId = profile.UserId;
                asmLogin.Domain = profile.Domain;
                
                asmLogin.Token = TokenManager.GenerateToken(profile, out expires, out loginTime);
                asmLogin.Expires = expires;
                asmLogin.Data = asmLogin.Token;
                asmLogin.LoginTime = loginTime.ToString(Util.GetTimeFormat());
                var userFetcher = new UserFetcher();
                var user = userFetcher.Get(asmLogin.UserId);
                if(user!=null)
                {
                    asmLogin.IsRetail = user.Retail;
                    asmLogin.IsSupplier = user.Supplier;
                    if (user.Retail)
                    {
                        var retailMemberFetcher = new RetailMemberFetcher();
                        var retail = retailMemberFetcher.GetByUser(user.AutoId);
                        if(retail!=null)
                        {
                            asmLogin.RetailId = retail.Retail;
                        }
                    }
                    if(user.Supplier)
                    {
                        var supplierMemberFetcher = new SupplierMemberFetcher();
                        var supplier = supplierMemberFetcher.GetByUser(user.AutoId);
                        if (supplier != null)
                        {
                            asmLogin.SupplierId = supplier.Supplier;
                        }
                    }
                }
                LogHelper.Log(this.GetType().Name, String.Format("GETTOKEN:用户 [{0}] [{1}]更新TOKEN成功", asmLogin.UserId, RequestIp));
            }
            else
            {
                Response.StatusCode = (int)HttpStatusCode.Unauthorized;
                asmLogin.Result = AmsCode.AuthFaild;
                asmLogin.Message = String.Format("刷新失败,{0}", profile.UserId);
                LogHelper.Err(this.GetType().Name, String.Format("GETTOKEN:客户端 [{0}] 尝试更新TOKEN失败", RequestIp));
            }
            LogHelper.Debug(this.GetType().Name, String.Format("GETTOKEN:[RSP|{1}]{0}", Util.ConvertToJson(asmLogin), RequestIp));

            DBHelper.Commit(true);
            return asmLogin;
        }
        [HttpGet]
        [Authorize]
        public AsmObject<string> Logout()
        {
            AsmObject<string> result = new AsmObject<string>();
            if (!String.IsNullOrWhiteSpace(access_token))
            {
                TokenManager.DisableToken(access_token);
                result.Data = "操作成功";
                result.Message = "操作成功";
                result.Result = AmsCode.Succ;
            }
            DBHelper.Commit(true);
            return result;
        }
        [HttpGet]
        [Authorize]
        public AsmObject<FullUserProfile> WhoAmI()
        {
            var result = new AsmObject<FullUserProfile>();
            if (profile != null)
            {
                result.Data = MyHttpContextHelper.ToFullUserProfile(profile);
                result.Message = "操作成功";
                result.Result = AmsCode.Succ;

            }
            else
            {
                result.Data = null;
                result.Message = "操作失败";
                result.Result = AmsCode.AuthFaild;
                Response.StatusCode = (int)HttpStatusCode.Unauthorized;
                LogHelper.Err(this.GetType(), String.Format("WHOAMI:客户端 [{0}] 请求信息失败", RequestIp));
            }
            LogHelper.Debug(this.GetType(), String.Format("WHOMAI:[RSP|{1}]{0}", Util.ConvertToJson(result), RequestIp));
            DBHelper.Commit(true);
            return result;
        }
        //SAMPLE FOR LoginModel {"UserId":"0","Pasword":"abc","Status":1}
        [HttpPost]
        [RoleFlagAuthorizeAttribute( PolicyDomain.Super, AppOpt.Create)]
        public AsmObject<bool> Register(dynamic dataJson)
        {
            LogHelper.Debug(this.GetType(), String.Format("REGISTER:[RQS|{1}]{0}", dataJson, RequestIp));
            int role = Int32.Parse((String)dataJson.role);
            int domain = Int32.Parse((String)dataJson.domain);
            LoginModel loginModel = Util.ConvertObjectFromJson<LoginModel>((String)dataJson.loginmodel);
            if (loginModel == null)
            {
                DBHelper.Commit(false);
                LogHelper.Err(this.GetType(), String.Format("REGISTER:从{0}中接收到空的参数", RequestIp));
                Response.StatusCode = (int)HttpStatusCode.BadRequest;
                var errResponse = new AsmObject<bool>() { Data = false, Message = "传入的参数不能为空", Result = AmsCode.ArgNotAccept };
                LogHelper.Debug(this.GetType(), String.Format("REGISTER:[RSP|{1}]{0}", Util.ConvertToJson(errResponse), RequestIp));
                return errResponse;
            }
            var result = manager.Register(loginModel,domain,role);
            LogHelper.Debug(this.GetType(), String.Format("REGISTER:[RSP|{1}]{0}", Util.ConvertToJson(result), RequestIp));
            DBHelper.Commit( true);
            return result;
        }
        [HttpGet]
        [RoleFlagAuthorizeAttribute(PolicyDomain.Super, AppOpt.Exec)]
        public AsmObject<bool> ExistLoginInfo(int userId)
        {
            LogHelper.Debug(this.GetType(), String.Format("EXISTLOGININFO:[RQS]{0}",  RequestIp));
            var login = fetcher.GetByUserId(userId);
            AsmObject<bool> result = new AsmObject<bool>() ;
            result.Message = "操作成功";
            result.Result = AmsCode.Succ;
            result.Data = (login != null);
            LogHelper.Debug(this.GetType(), String.Format("REGISTER:[RSP|{1}]{0}", Util.ConvertToJson(result), RequestIp));
            DBHelper.Commit(true);
            return result;
        }
        //SAMPLE FOR LoginModel {"UserId":"0","Pasword":"abc"}
        [HttpPost]
        [RoleFlagAuthorizeAttribute( PolicyDomain.Super, AppOpt.Func1)]
        public AsmObject<bool> ChangePassword(LoginModel loginModel)
        {
            LogHelper.Debug(this.GetType(), String.Format("CHANGEPASSWORD:[RQS|{1}]{0}", Util.ConvertToJson(loginModel), RequestIp));
            if (loginModel == null)
            {
                DBHelper.Commit( false);
                LogHelper.Err(this.GetType(), String.Format("CHANGEPASSWORD:从{0}接收到空的参数", RequestIp));
                Response.StatusCode = (int)HttpStatusCode.BadRequest;
                var errResponse = new AsmObject<bool>() { Data = false, Message = "传入的参数不能为空", Result = AmsCode.ArgNotAccept };
                LogHelper.Debug(this.GetType(), String.Format("REGISTER:[RSP|{1}]{0}", Util.ConvertToJson(errResponse), RequestIp));
                return errResponse;
            }
            var result = manager.ChangePassword(loginModel.UserId, loginModel.Password);
            LogHelper.Log(this.GetType(), String.Format("CHANGEPASSWORD:用户{0}修改密码{1}[{2}]", loginModel.UserId, (result.Result == AmsCode.Succ ? "Succ" : "Fault"), RequestIp));
            DBHelper.Commit( true);
            LogHelper.Debug(this.GetType(), String.Format("REGISTER:[RSP|{1}]{0}", Util.ConvertToJson(result), RequestIp));
            return result;
        }
        //SAMPLE FOR LoginModel {"UserId":"0","Pasword":"abc"}
        [HttpPost]
        [Authorize]
        public AsmObject<bool> ChangeMyPassword(LoginModel loginModel)
        {
            LogHelper.Debug(this.GetType(), String.Format("CHANGEMYPASSWORD:[RQS|{1}]{0}", Util.ConvertToJson(loginModel), RequestIp));
            if (loginModel == null)
            {
                DBHelper.Commit( true);
                LogHelper.Err(this.GetType(), String.Format("CHANGEMYPASSWORD:从{0}中接收到空的参数", RequestIp));
                Response.StatusCode = (int)HttpStatusCode.BadRequest;
                var errResponse = new AsmObject<bool>() { Data = false, Message = "传入的参数不能为空", Result = AmsCode.ArgNotAccept };
                LogHelper.Debug(this.GetType(), String.Format("CHANGEMYPASSWORD:[RSP|{1}]{0}", Util.ConvertToJson(errResponse), RequestIp));
                return errResponse;
            }
            if (profile == null)
            {
                DBHelper.Commit( true);
                LogHelper.Err(this.GetType(), String.Format("CHANGEMYPASSWORD:无法取得取得当前用户的Profile,{0}", RequestIp));
                Response.StatusCode = (int)HttpStatusCode.Unauthorized;
                var errResponse = new AsmObject<bool>() { Data = false, Message = "当前用户没有登录", Result = AmsCode.AuthFaild };
                LogHelper.Debug(this.GetType(), String.Format("CHANGEMYPASSWORD:[RSP|{1}]{0}", Util.ConvertToJson(errResponse), RequestIp));
                return errResponse;
            }
            if (loginModel.UserId != profile.UserId)
            {
                DBHelper.Commit( true);
                Response.StatusCode = (int)HttpStatusCode.Forbidden;
                LogHelper.Err(this.GetType(), String.Format("CHANGEMYPASSWORD:用户:{0}/{1}尝试修改其他用户{2}的密码", profile.UserId, RequestIp, loginModel.UserId));
                var errResponse = new AsmObject<bool>() { Data = false, Message = "尝试修改其他用户的密码", Result = AmsCode.NotSupport };
                LogHelper.Debug(this.GetType(), String.Format("CHANGEMYPASSWORD:[RSP|{1}]{0}", Util.ConvertToJson(errResponse), RequestIp));
                return errResponse;
            }
            var result = manager.ChangePassword(loginModel.UserId, loginModel.Password);
            LogHelper.Log(this.GetType(), String.Format("CHANGEMYPASSWORD:用户{0}修改密码{1}[{2}]", loginModel.UserId, (result.Result == AmsCode.Succ ? "Succ" : "Fault"), RequestIp));
            DBHelper.Commit( true);
            LogHelper.Debug(this.GetType(), String.Format("CHANGEMYPASSWORD:[RSP|{1}]{0}", Util.ConvertToJson(result), RequestIp));
            return result;
        }
        //SAMPLE FOR LoginModel {"UserId":"0","Status":"1"}
        [HttpPost]
        [RoleFlagAuthorizeAttribute( PolicyDomain.Super, AppOpt.Create)]
        public AsmObject<bool> Lock(LoginModel loginModel)
        {
            if (loginModel == null)
            {
                LogHelper.Warn(this.GetType(), String.Format("LOCK:从{0}中接收到空的参数", RequestIp));
                Response.StatusCode = (int)HttpStatusCode.BadRequest;
                return new AsmObject<bool>() { Data = false, Message = "传入的参数不能为空", Result = AmsCode.ArgNotAccept };
            }
            AsmObject<bool> result = manager.Lock(loginModel.UserId, loginModel.Status);
            LogHelper.Log(this.GetType(), String.Format("LOCK:用户{0}锁定{1}[{2}]", loginModel.UserId, (result.Result == AmsCode.Succ ? "Succ" : "Fault"), RequestIp));
            DBHelper.Commit( true);
            return result;
        }
        [HttpPost]
        [RoleFlagAuthorizeAttribute( PolicyDomain.Super,AppOpt.Create)]
        public AsmObject<UserModel> Set(UserModel userModel)
        {
            if(userModel==null)
            {
                LogHelper.Warn(this.GetType(), String.Format("SET:从{0}中接收到空的参数", RequestIp));
                Response.StatusCode = (int)HttpStatusCode.BadRequest;
                return new AsmObject<UserModel>() { Message = "传入的参数不能为空", Result = AmsCode.ArgNotAccept };
            }
            AsmObject<UserModel> result = uManager.Set(userModel);
            LogHelper.Log(this.GetType(), String.Format("SET:用户{0}保存{1}[{2}]", userModel.AutoId, (result.Result == AmsCode.Succ ? "Succ" : "Fault"), RequestIp));
            DBHelper.Commit( true);
            return result;
        }
        [HttpPost]
        [RoleFlagAuthorizeAttribute( PolicyDomain.Super, AppOpt.Delete)]
        public AsmObject<bool> Del(UserModel userModel)
        {
            LogHelper.Debug(this.GetType(), String.Format("DEL:[RQS|{1}]{0}", Util.ConvertToJson(userModel), RequestIp));
            if (userModel == null)
            {
                LogHelper.Err(this.GetType(), String.Format("DEL:从{0}中接收到空的参数", RequestIp));
                Response.StatusCode = (int)HttpStatusCode.BadRequest;
                var errResponse = new AsmObject<bool>() { Data = false, Message = "传入的参数不能为空", Result = AmsCode.ArgNotAccept };
                LogHelper.Debug(this.GetType(), String.Format("DEL:[RSP|{1}]{0}", Util.ConvertToJson(errResponse), RequestIp));
                return errResponse;
            }
            AsmObject<bool> result = uManager.Delete(userModel);
            LogHelper.Log(this.GetType(), String.Format("SET:用户{0}删除{1}[{2}]", userModel.AutoId, (result.Result == AmsCode.Succ ? "Succ" : "Fault"), RequestIp));
            DBHelper.Commit( true);
            LogHelper.Debug(this.GetType(), String.Format("DEL:[RSP|{1}]{0}", Util.ConvertToJson(result), RequestIp));
            return result;
        }
        [HttpPost]
        [RoleFlagAuthorizeAttribute(PolicyDomain.Super, AppOpt.Delete)]
        public AsmArray<Int32> BulkDel(dynamic jsonUserModel)
        {
            LogHelper.Debug(this.GetType(), String.Format("BULKDEL:[RQS|{1}]{0}", jsonUserModel, RequestIp));
            var models = Util.ConvertArrayFromJson<UserModel>((String)jsonUserModel.data);
            if (models == null)
            {
                LogHelper.Err(this.GetType(), String.Format("BULKDEL:从{0}中接收到空的参数", RequestIp));
                Response.StatusCode = (Int32)HttpStatusCode.BadRequest;
                var errResponse = new AsmArray<Int32>() { Data = new List<Int32>(), Message = "传入的参数不能为空", Result = AmsCode.ArgNotAccept };
                LogHelper.Debug(this.GetType(), String.Format("BULKDEL:[RSP|{1}]{0}", Util.ConvertToJson(errResponse), RequestIp));
                return errResponse;
            }
            int faild = models.Count();
            var del = new List<Int32>();
            StringBuilder sb = new StringBuilder();
            foreach(var model in models)
            {
                var eff = uManager.Delete(model);
                if(eff.Result!=0)
                {
                    sb.AppendFormat("{0}:{1}\r\n", model.AutoId, eff.Message);
                }
                else
                {
                    del.Add(model.AutoId);
                    faild--;
                }
            }
            DBHelper.Commit(true);
            var succResponse = new AsmArray<Int32>() { Data = del, Message = "共有"+ (models.Count() - faild) + "笔资料删除成功", Result = AmsCode.Succ };
            LogHelper.Debug(this.GetType(), String.Format("DEL:[RSP|{1}]{0}", Util.ConvertToJson(succResponse), RequestIp));
            return succResponse;
        }
        [HttpGet]
        [Authorize]
        public AsmArray<UserModel> List(string jsonCondition,int pos,int size)
        {
            LogHelper.Debug(this.GetType(), String.Format("LIST:[RQS|{1}]{0}", jsonCondition, RequestIp));
            int cnt = 0;
            var userList = userFetcher.List(Util.ConvertArrayFromJson<Condition>(jsonCondition), pos, size, out cnt);
            DBHelper.Commit( true);
            var result = new AsmArray<UserModel>() { Data = userList, Message = "操作成功", Result = AmsCode.Succ ,Cnt = cnt};
            LogHelper.Debug(this.GetType(), String.Format("LIST:[RSP|{1}]{0}", Util.ConvertToJson(result), RequestIp));
            return result;
        }
        [HttpGet]
        [RoleFlagAuthorizeAttribute(PolicyDomain.Ignore, AppOpt.Exec)]
        public AsmArray<UserModel> SearchByName(string name)
        {
            LogHelper.Debug(this.GetType(), String.Format("SEARCHBYNAME:[RQS|{1}]{0}", name, RequestIp));
            int cnt = 0;
            var conditions = new Condition[] { new Condition() { Key="Name",Op="like", Value = "%"+name+"%" } };
            var userList = userFetcher.List(conditions);
            DBHelper.Commit(true);
            var result = new AsmArray<UserModel>() { Data = userList, Message = "操作成功", Result = AmsCode.Succ, Cnt = cnt };
            LogHelper.Debug(this.GetType(), String.Format("SEARCHBYNAME:[RSP|{1}]{0}", Util.ConvertToJson(result), RequestIp));
            return result;
        }
        [HttpGet]
        [Authorize]
        public AsmObject<UserModel> Get(int uid)
        {
            LogHelper.Debug(this.GetType(), String.Format("GET:[RQS|{1}]{0}", Util.ConvertToJson(uid), RequestIp));
            UserModel user = userFetcher.Get(uid);
            DBHelper.Commit( true);
            AsmObject<UserModel> result = null;
            if(user!=null)
                result = new AsmObject<UserModel>() { Data = user, Message = "操作成功", Result = AmsCode.Succ };
            else
                result = new AsmObject<UserModel>() { Data = user, Message = "找不到数据", Result = AmsCode.DataNotFound };
            LogHelper.Debug(this.GetType(), String.Format("GET:[RSP|{1}]{0}", Util.ConvertToJson(result), RequestIp));
            return result;
        }
    }
}